<?php
/**
 * Hooks for TranslatedPages extension
 *
 * @file
 * @ingroup Extensions
 */

class TranslatedPagesHooks {
    private static $version;
    private static $sidebar = false;
    
    public static function defineHooks( &$parser ) {
	global $wgHooks;
	
	$parser->setFunctionHook( 'translatedpages', 'TranslatedPagesHooks::setupActions' );
	//$wgHooks['PageHistoryBeforeList'][] = 'TranslatedPagesHooks::showCurrentVersion';
	$wgHooks['PageHistoryLineEnding'][] = 'TranslatedPagesHooks::addRevisionId';
	$wgHooks['SkinBuildSidebar'][] = 'TranslatedPagesHooks::sidebarLanguages';
	return true;
    }
    
    public static function setupActions( &$parser ) {
	$args = func_get_args();
	array_shift( $args );
	$array = self::checkVars( $args );
	
	if ( count( $array ) == 0 ) {
	    self::$sidebar = true;
	} else {
	    $output = '';
	    
	    $keys = array_keys( $array );
	    
	    switch ( $keys[0] ) {
	    case 'revision':
		self::$version = $array[$keys[0]];
		self::$sidebar = true;
		
		if ( isset( $keys[1] ) && ( $keys[1] == 'outdated') ) {
		    $output .= self::getMessage( $array[$keys[1]] );
		}
		break;
	    case 'showstatus':
		$lang = '';
		
		if ( isset( $keys[1] ) && ( $keys[1] == 'lang') ) {
		    $lang = $array[$keys[1]];
		}
		
		$output .= self::showstatus($lang);
		break;
	    default:
		$output .= self::getError( 'translatedpages-syntax-error' );
		break;
	    }
	    
	    return $output;
	}
    }
    
    private static function checkVars( $args ) {
	$array = array();
	
	if ( count( $args ) == 1 && $args[0] == '' ) {
	    $array = array();
	} else {
	    foreach ( $args as $val ) {
		$valFilter = str_replace( '\=', '\&#61;', $val );
		$parts = explode( '=', $valFilter );
		
		if ( count( $parts ) > 2 ) {
		    //$this->error = true;
		    return false;
		}
		
		$key = trim( $parts[0] );
		$value = ( isset ( $parts[1] ) ) ? trim( str_replace( '\&#61;', '=', $parts[1] ) ) : '';
		$array[ $key ] = $value;
	    }
	}
	
	return $array;
    }
    
    public static function sidebarLanguages( $skin, &$bar ) {
	global $wgRequest, $wgTranslatedPagesSourceLanguage;
	
	if (self::$sidebar == false) {
	    return true;
	}
	$title = $wgRequest->getVal('title');
	
	$titleObject = Title::newFromText($title);
	if ($titleObject->isSpecialPage()) {
	    return true;
	}
	
	$array = explode(':', $title, 2);
	
	if (count($array) == 2) {
	    //Cualquier idioma
	    $lang = strtolower($array[0]);
	    $title = $array[1];
	    $titleSource = Title::newFromText($title);
	    
	    if (!$titleSource->exists()) {
		return true;
	    }
	} else {
	    //Ingles
	    $lang = $wgTranslatedPagesSourceLanguage;
	}
	
	$list = self::searchList($title);
	
	if (count($list) >= 2) {
	    $bar['translatedpages'] = self::makeLinks($title, $lang, $list);
	}
	
	return true;
    }

    protected static function searchList( $title ) {
	global $wgTranslatedPagesSourceLanguage;
	
	$list = array();
	$languages = Language::getLanguageNames();
	$list[$wgTranslatedPagesSourceLanguage] = $languages[$wgTranslatedPagesSourceLanguage];
	unset($languages[$wgTranslatedPagesSourceLanguage]);
	$codes = array_keys($languages);
	$size = sizeof($codes);
	
	for ($i=0; $i<$size; $i++) {
	    $titleSource = Title::newFromText(ucfirst($codes[$i]).':'.$title);
	    
	    if ($titleSource->exists()) {
		$list[$codes[$i]] = $languages[$codes[$i]];
	    }
	}

	return $list;
    }

    protected static function makeLinks( $title, $lang, $list ) {
	global $wgRequest, $wgTranslatedPagesSourceLanguage;

	$html = '<ul>';
	foreach ($list as $key => $value) {
	    $html .= '<li>';
	    $titleOption = ($wgTranslatedPagesSourceLanguage != $key) ? ucfirst($key).':'.$title : $title;
	    $titleObject = Title::newFromText($titleOption);
	    $html .= ($lang != $key) ? '<a href="'.$titleObject->getFullURL().'">'.$value.'</a>' : '<b>'.$value.'</b>';
	    $html .= '</li>';
	}
	
	if ($wgRequest->getVal('title') != $title) {
	    $html .= self::makeVersions($wgRequest->getVal('title'), $title);
	}
	
	$html .= '</ul>';
	
	return $html;
    }
    
    protected static function makeVersions( $titleSource, $title ) {
	global $wgServer, $wgScript;
	$idRevSource = Article::newFromId(Title::newFromText($title)->getArticleId())->getLatest();
	$html = '<li><a href="'.$wgServer.$wgScript.'?title='.$titleSource.'&diff='.$idRevSource.'&oldid='.self::$version.'">@'.self::$version.' - @'.$idRevSource.'</a></li>';
	return $html;
    }
    
    public static function showCurrentVersion( $article ) {
	$tag = '<b>' . wfMsg('translatedpages-current-version') . ' : </b>' . $article->getLatest();
	$output = RequestContext::getMain()->getOutput();
	$output->addHTML( $tag );
	return true;
    }
    
    public static function addRevisionId( $history, &$row, &$s, &$classes ) {
	$revId = ($row->rev_id < 10) ? "&nbsp;&nbsp;$row->rev_id" : $row->rev_id;
	$s = "<b>$revId</b> $s";
	return true;
    }
    
    private static function getMessage( $message ) {
	return '<p style="background-color: rgb(253, 255, 221); padding: 10pt; border-color: rgb(128, 128, 128); border-style: solid; border-width: 1px;">' . $message . '</p>';
    }
    
    private static function getError( $error ) {
	return '<p style="color:rgb(255, 0, 0);"><b>' . wfMsg( $error ) . '</b></p>';
    }
    
    private static function showstatus ($lang) {
	global $wgTranslatedPagesSourceLanguage, $wgTranslatedPagesColorsStates;
	
	$ret = self::getSources();

	if ($lang) {
	    $rets = '<table class="wikitable">';
	    $size = count($ret);
	    
	    for ($i = 0; $i < $size; $i++) {
		$title = ucfirst($lang).':'.$ret[$i]['title'];
		$status = self::getStatus( $ret[$i], $lang );
		$rets .= '<tr><td style="background-color:'.$wgTranslatedPagesColorsStates[$status].';">[['.$title.'|'.$ret[$i]['title'].']]</td></tr>';
	    }
	    
	    $rets .='</table>';
	} else {
	    $lang = array('en' =>'English', 'es' => 'Spanish', 'fr' => 'French');
	    unset($lang[$wgTranslatedPagesSourceLanguage]);
	    $rets = '<table class="wikitable"><tr><th>Page</th>';
	    
	    foreach ($lang as $id => $title) {
		$rets .= '<th>'.ucfirst($id).'</th>';
	    }
	    $rets .= '</tr>';
	    
	    for ($i = 0; $i < count($ret); $i++) {
		$rets .= '<tr><td>[['.$ret[$i]['title'].']]</td>';
		foreach ($lang as $key => $title) {
		    $title = ucfirst($key).':'.$ret[$i]['title'];
		    $status = self::getStatus( $ret[$i], $key);
		    $rets .= '<td style="background-color:'.$wgTranslatedPagesColorsStates[$status].';">[['.$title.'|'.$key.']]</td>';
		}
		$rets .= '</tr>';
	    }
	    $rets .= '</table>';
	}
	
	return $rets;
    }
    
    private static function getSources() {
	$dbr = wfGetDB( DB_SLAVE );
	$res = $dbr->select(
	    array( 'page', 'text' ),
	    array( 'page_latest', 'page_title' ),
	    "page_latest=old_id AND old_text LIKE '%{{#TranslatedPages:}}%'",
	    __METHOD__,
	    array( 'ORDER BY' => 'page_title ASC' )
	    );
	
	$ret = array();
	$i = 0;
	
	while ($row = $dbr->fetchObject($res)) {
	    $ret[$i]['id'] = $row->page_latest;
	    $ret[$i]['title'] = $row->page_title;
	    ++$i;
	}
	
	$dbr->freeResult($res);
	
	return $ret;
    }
    
    private static function getStatus( $ret, $lang = '' ) {
	global $wgTranslatedPagesColorsStates;
	
	$lang = ($lang != '') ? ucfirst($lang).':' : '';
	$title = $lang.$ret['title'];
	$titleObject = Title::newFromText($title);
	$status = '';
	
	if ( !$titleObject->exists() ) {
	    $status = 'missing';
	} else {
	    $id = Title::newFromText($title)->getArticleID();
	    $myArticle = Article::newFromId($id);
	    $text = $myArticle->getRawText();
	    preg_match("#^\{\{\#TranslatedPages:revision=([0-9]+).*\}\}#is", $text, $num);
	    
	    if ( !isset($num[1]) ) {
		$status = 'error';
	    } else {
		if ($num[1] == $ret['id']) {
		    $status = 'updated';
		} else {
		    $status = 'outdated';
		}
	    }
	}
	
	return $status;
    }
}